<template>
  <BkSideslider
    v-model:is-show="visible"
    v-bind="$attrs"
    :before-close="handleBeforeClose"
  >
    <template #header>
      <slot
        v-if="slots.header"
        name="header"
      />
      <div v-else>
        {{ title }}
      </div>
    </template>
    <slot name="default" />
    <template
      v-if="showFooter"
      #footer
    >
      <slot
        v-if="slots.footer"
        name="footer"
      />
      <div v-else>
        <BkButton
          theme="primary"
          class="mr-12px"
          @click="handleConfirmClick"
        >
          确定
        </BkButton>
        <BkButton
          @click="handleCancelClick"
        >
          取消
        </BkButton>
      </div>
    </template>
  </BkSideslider>
</template>

<script setup lang="ts">
import { InfoBox } from 'bkui-vue';
import { isEqual, isFunction, isObject } from 'lodash-es';

interface IProps {
  title?: string
  showFooter?: boolean
  closeConfirm?: boolean | { text: string }
  currentState?: any
  equal?: (a: any, b: any) => boolean
}

const visible = defineModel<boolean>({ default: false });

const {
  title = '',
  showFooter = true,
  closeConfirm = false,
  currentState = undefined,
  equal = undefined,
} = defineProps<IProps>();

const emits = defineEmits<{
  confirm: [void]
  cancel: [void]
}>();

const slots = defineSlots<{
  default: () => any
  header?: () => any
  footer?: () => any
}>();

let initState: any = undefined;

const compare = (a: any, b: any) => isFunction(equal) ? equal(a, b) : isEqual(a, b);

const handleBeforeClose = () => {
  if (!closeConfirm || compare(initState, currentState)) {
    return true;
  }
  return new Promise((resolve, reject) => {
    InfoBox({
      title: isObject(closeConfirm) && closeConfirm?.text ? closeConfirm.text : '确认关闭?',
      infoType: 'warning',
      onConfirm: () => {
        emits('confirm');
        return resolve(true);
      },
      onCancel: () => reject(),
    });
  });
};

const handleConfirmClick = () => {
  emits('confirm');
};

const handleCancelClick = () => {
  emits('cancel');
};

defineExpose({
  show: () => visible.value = true,
  setInitData: (state: any) => initState = state,
});
</script>

<style scoped lang="scss">

</style>
